package com.huaxonline.boot.web.sign;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;
import java.util.TreeMap;

/**
 * 签名工具类
 * @author zhaoshulei
 * @since 2023/9/13
 */
@Slf4j
public class SignUtil {

    /**
     * 检查请求签名
     */
    public static void checkRequest() {
        SignTemplate.getInstance().checkRequest();
    }

    /**
     * 检查参数映射签名
     */
    public static void checkParamMap(Map<String, String> paramMap) {
        SignTemplate.getInstance().checkParamMap(paramMap);
    }
    
    /**
     * 生成签名客户端
     */
    public static SignClient createClient(String appId, String secret) {
        return new SignClient(appId, secret);
    }
    
    /**
     * 生成签名客户端（指定算法）
     */
    public static SignClient createClient(String appId, String secret, SignAlgorithm algorithm) {
        return new SignClient(appId, secret, algorithm);
    }
    
    /**
     * 快速生成签名
     */
    public static String quickSign(String appId, String secret, Map<String, Object> params) {
        SignClient client = createClient(appId, secret);
        long timestamp = System.currentTimeMillis();
        String nonce = IdUtil.fastSimpleUUID();
        
        Map<String, Object> signParams = new TreeMap<>(params);
        signParams.put(SignConstants.HEADER_TIMESTAMP, timestamp);
        signParams.put(SignConstants.HEADER_NONCE, nonce);
        
        return client.generateSign(signParams);
    }
    
    /**
     * 快速生成签名（包含请求体）
     */
    public static String quickSignWithBody(String appId, String secret, Map<String, Object> params, String body) {
        SignClient client = createClient(appId, secret);
        long timestamp = System.currentTimeMillis();
        String nonce = IdUtil.fastSimpleUUID();
        
        Map<String, Object> signParams = new TreeMap<>(params);
        signParams.put(SignConstants.HEADER_TIMESTAMP, timestamp);
        signParams.put(SignConstants.HEADER_NONCE, nonce);
        
        return client.generateSignWithBody(signParams, body);
    }
    
    /**
     * 验证时间戳
     */
    public static boolean isValidTimestamp(long timestamp, long disparity) {
        long timeDiff = Math.abs(System.currentTimeMillis() - timestamp);
        return disparity == -1L || timeDiff <= disparity;
    }
    
    /**
     * 生成随机nonce
     */
    public static String generateNonce() {
        return IdUtil.fastSimpleUUID();
    }
    
    /**
     * 生成时间戳
     */
    public static long generateTimestamp() {
        return System.currentTimeMillis();
    }
    
    /**
     * 构建签名参数字符串
     */
    public static String buildSignString(Map<String, Object> params, String secret) {
        StringBuilder sb = new StringBuilder();
        sb.append(SignConstants.HEADER_SECRET).append("=").append(secret).append("&");
        
        Map<String, Object> sortedParams = new TreeMap<>(params);
        for (Map.Entry<String, Object> entry : sortedParams.entrySet()) {
            if (entry.getValue() != null && StrUtil.isNotBlank(entry.getValue().toString())) {
                sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
            }
        }
        
        if (sb.length() > 0) {
            sb.deleteCharAt(sb.length() - 1);
        }
        
        return sb.toString();
    }
}
